package lockDemo;

import java.util.concurrent.locks.AbstractQueuedSynchronizer;

/**
 * @author Ajie
 * @date 8/23/21
 * @function 一个简单的 AQS 同步类
 *  https://www.cnblogs.com/xiaofuge/p/13962193.html
 */
public class AQS_Demo {
    public static void main(String[] args) {
        try {
            final SyncLock lock = new SyncLock();
            for (int i = 0; i < 200000; i++) {
//                Thread.sleep(10);
                new Thread(new TestLock(lock), String.valueOf(i)).start();
            }
            System.out.println(String.format("result >>>>>>>>>> %d",TestLock.count));
            Thread.sleep(100000);
        }catch (Exception e){
            e.printStackTrace();
        }

    }

    static class TestLock implements Runnable {
        private SyncLock lock;
        private volatile static int count;
        public TestLock(SyncLock lock) throws InterruptedException {
            this.lock = lock;
        }
        @Override
        public void run() {
            try {
                lock.lock();
//                Thread.sleep(10);
                count++;
                System.out.println(String.format("Thread %s Completed-- %d", Thread.currentThread().getName(),count));
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }
}

class SyncLock{

    //内部 state 在哪？？？



    private final Sync sync;

    public SyncLock() {
        this.sync = new Sync();
    }
    public void lock() {
        sync.acquire(1);
    }

    public void unlock() {
        sync.release(1);
    }

    private static class Sync extends AbstractQueuedSynchronizer{
        @Override
        protected boolean tryAcquire(int arg) {
//            return super.tryAcquire(arg);
            int state = getState();
            return compareAndSetState(state,state+arg);
        }

        @Override
        protected boolean tryRelease(int arg) {
            int state = getState();
            setState(state-arg);
            return (state-arg)==0;//is free
        }

        // 该线程是否正在独占资源，只有用到 Condition 才需要去实现???? 待验证。
        @Override
        protected boolean isHeldExclusively() {
//            return super.isHeldExclusively();
//            return getState() == 1;

            return getExclusiveOwnerThread() == Thread.currentThread();//reen
        }
    }
}